/*      */ package com.zimbra.cs.mailbox;
/*      */ 
/*      */ import com.google.common.base.Objects.ToStringHelper;
/*      */ import com.zimbra.common.mailbox.Color;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.util.ArrayUtil;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.StringUtil;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.cs.account.AccessManager;
/*      */ import com.zimbra.cs.account.Account;
/*      */ import com.zimbra.cs.db.DbMailItem;
/*      */ import com.zimbra.cs.imap.ImapSession;
/*      */ import com.zimbra.cs.mailbox.util.TypedIdList;
/*      */ import com.zimbra.cs.session.Session;
/*      */ import com.zimbra.cs.session.Session.Type;
/*      */ import com.zimbra.cs.util.AccountUtil;
/*      */ import com.zimbra.soap.mail.type.RetentionPolicy;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Arrays;
/*      */ import java.util.Collections;
/*      */ import java.util.Date;
/*      */ import java.util.EnumSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Set;
/*      */ 
/*      */ public class Folder extends MailItem
/*      */ {
/*      */   public static final byte FOLDER_IS_IMMUTABLE = 1;
/*      */   public static final byte FOLDER_DONT_TRACK_COUNTS = 2;
/*      */   protected byte attributes;
/*      */   protected MailItem.Type defaultView;
/*      */   private Map<String, Folder> subfolders;
/*      */   private long totalSize;
/*      */   private Folder parent;
/*      */   private SyncData syncData;
/*      */   private int imapUIDNEXT;
/*      */   private int imapMODSEQ;
/*      */   private int imapRECENT;
/*      */   private int imapRECENTCutoff;
/*      */   private int deletedCount;
/*      */   private int deletedUnreadCount;
/*      */   private RetentionPolicy retentionPolicy;
/*      */   private boolean activeSyncDisabled;
/*      */   private int webOfflineSyncDays;
/*      */   protected static final String CN_NAME = "n";
/*      */   protected static final String CN_ATTRIBUTES = "attributes";
/*      */   private static final String CN_DELETED = "deleted";
/*      */   private static final String CN_DELETED_UNREAD = "del_unread";
/*      */   
/*      */   public static class FolderOptions
/*      */   {
/*      */     private byte attributes;
/*   56 */     private MailItem.Type defaultView = MailItem.Type.UNKNOWN;
/*      */     private int flags;
/*   58 */     private Color color = MailItem.DEFAULT_COLOR_RGB;
/*      */     private String url;
/*      */     private Long date;
/*      */     private String uuid;
/*      */     private MailItem.CustomMetadata custom;
/*      */     
/*      */     public FolderOptions setAttributes(byte attributes) {
/*   65 */       this.attributes = attributes;
/*   66 */       return this;
/*      */     }
/*      */     
/*      */     public byte getAttributes() {
/*   70 */       return this.attributes;
/*      */     }
/*      */     
/*      */     public FolderOptions setDefaultView(MailItem.Type view) {
/*   74 */       if (view != null) {
/*   75 */         this.defaultView = view;
/*      */       }
/*   77 */       return this;
/*      */     }
/*      */     
/*      */     public MailItem.Type getDefaultView() {
/*   81 */       return this.defaultView;
/*      */     }
/*      */     
/*      */     public FolderOptions setFlags(int flags) {
/*   85 */       this.flags = flags;
/*   86 */       return this;
/*      */     }
/*      */     
/*      */     public int getFlags() {
/*   90 */       return this.flags;
/*      */     }
/*      */     
/*      */     public FolderOptions setColor(byte bcolor) {
/*   94 */       return setColor(new Color(bcolor));
/*      */     }
/*      */     
/*      */     public FolderOptions setColor(Color color) {
/*   98 */       this.color = color;
/*   99 */       return this;
/*      */     }
/*      */     
/*      */     public Color getColor() {
/*  103 */       return this.color;
/*      */     }
/*      */     
/*      */     public FolderOptions setUrl(String url) {
/*  107 */       this.url = url;
/*  108 */       return this;
/*      */     }
/*      */     
/*      */     public String getUrl() {
/*  112 */       return this.url;
/*      */     }
/*      */     
/*      */     public FolderOptions setDate(Long date) {
/*  116 */       this.date = date;
/*  117 */       return this;
/*      */     }
/*      */     
/*      */     public Long getDate() {
/*  121 */       return this.date;
/*      */     }
/*      */     
/*      */     public FolderOptions setUuid(String uuid) {
/*  125 */       this.uuid = uuid;
/*  126 */       return this;
/*      */     }
/*      */     
/*      */     public String getUuid() {
/*  130 */       return this.uuid;
/*      */     }
/*      */     
/*      */     public FolderOptions setCustomMetadata(MailItem.CustomMetadata custom) {
/*  134 */       this.custom = custom;
/*  135 */       return this;
/*      */     }
/*      */     
/*      */     public MailItem.CustomMetadata getCustomMetadata() {
/*  139 */       return this.custom;
/*      */     }
/*      */   }
/*      */   
/*      */   public static final class SyncData {
/*      */     String url;
/*      */     String lastGuid;
/*      */     long lastDate;
/*      */     boolean stop;
/*      */     
/*      */     SyncData(String url) {
/*  150 */       this.url = url;
/*      */     }
/*      */     
/*      */     SyncData(SyncData sd) {
/*  154 */       this(sd.url, sd.lastGuid, sd.lastDate);
/*      */     }
/*      */     
/*      */     SyncData(String url, String guid, long date) {
/*  158 */       this.url = url;
/*  159 */       this.lastGuid = (guid == null ? null : guid.trim());
/*  160 */       this.lastDate = date;
/*      */     }
/*      */     
/*      */     public boolean alreadySeen(String guid, Date date) {
/*  164 */       if (date != null)
/*  165 */         return this.lastDate >= date.getTime();
/*  166 */       if (this.stop)
/*  167 */         return true;
/*  168 */       if ((guid == null) || (this.lastGuid == null) || (!guid.trim().equalsIgnoreCase(this.lastGuid))) {
/*  169 */         return false;
/*      */       }
/*  171 */       return this.stop = 1;
/*      */     }
/*      */     
/*      */     public long getLastSyncDate() {
/*  175 */       return this.lastDate;
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   Folder(Mailbox mbox, MailItem.UnderlyingData ud)
/*      */     throws ServiceException
/*      */   {
/*  198 */     this(mbox, ud, false);
/*      */   }
/*      */   
/*      */   Folder(Mailbox mbox, MailItem.UnderlyingData ud, boolean skipCache) throws ServiceException {
/*  202 */     super(mbox, ud, skipCache);
/*      */     
/*  204 */     switch (getType()) {
/*      */     case FOLDER: 
/*      */     case SEARCHFOLDER: 
/*      */     case MOUNTPOINT: 
/*      */       break;
/*      */     default: 
/*  210 */       throw new IllegalArgumentException();
/*      */     }
/*      */     
/*  213 */     assert (this.retentionPolicy != null);
/*      */   }
/*      */   
/*      */   public String getSender() {
/*  217 */     return "";
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public String getPath()
/*      */   {
/*  225 */     if ((this.mId == 11) || (this.mId == 1)) {
/*  226 */       return "/";
/*      */     }
/*  228 */     String parentPath = this.parent.getPath();
/*  229 */     return parentPath + (parentPath.equals("/") ? "" : "/") + getName();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public MailItem.Type getDefaultView()
/*      */   {
/*  238 */     return this.defaultView;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public byte getAttributes()
/*      */   {
/*  245 */     return this.attributes;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public long getItemCount()
/*      */   {
/*  253 */     return getSize();
/*      */   }
/*      */   
/*      */   public int getDeletedCount() {
/*  257 */     return this.deletedCount;
/*      */   }
/*      */   
/*      */   public int getDeletedUnreadCount() {
/*  261 */     return this.deletedUnreadCount;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public long getTotalSize()
/*      */   {
/*  269 */     return this.totalSize;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public String getUrl()
/*      */   {
/*  276 */     return (this.syncData == null) || (this.syncData.url == null) ? "" : this.syncData.url;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public SyncData getSyncData()
/*      */   {
/*  283 */     return this.syncData == null ? null : new SyncData(this.syncData);
/*      */   }
/*      */   
/*      */ 
/*      */   public long getLastSyncDate()
/*      */   {
/*  289 */     return this.syncData == null ? 0L : this.syncData.lastDate;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public int getImapRECENTCutoff()
/*      */   {
/*  298 */     for (Session s : this.mMailbox.getListeners(Session.Type.IMAP)) {
/*  299 */       ImapSession i4session = (ImapSession)s;
/*  300 */       if ((i4session.getFolderId() == this.mId) && (i4session.isWritable()))
/*  301 */         return this.mMailbox.getLastItemId();
/*      */     }
/*  303 */     return this.imapRECENTCutoff;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   int getImapRECENT()
/*      */     throws ServiceException
/*      */   {
/*  316 */     if (getSize() == 0L) {
/*  317 */       return 0;
/*      */     }
/*      */     
/*  320 */     for (Session s : this.mMailbox.getListeners(Session.Type.IMAP)) {
/*  321 */       ImapSession i4session = (ImapSession)s;
/*  322 */       if ((i4session.getFolderId() == this.mId) && (i4session.isWritable())) {
/*  323 */         return 0;
/*      */       }
/*      */     }
/*      */     
/*  327 */     if (this.imapRECENT >= 0) {
/*  328 */       return this.imapRECENT;
/*      */     }
/*      */     
/*  331 */     markItemModified(16);
/*  332 */     this.imapRECENT = DbMailItem.countImapRecent(this, getImapRECENTCutoff());
/*  333 */     return this.imapRECENT;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public int getImapUIDNEXT()
/*      */   {
/*  340 */     return this.imapUIDNEXT;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public int getImapMODSEQ()
/*      */   {
/*  348 */     return this.imapMODSEQ;
/*      */   }
/*      */   
/*      */   public MailItem snapshotItem() throws ServiceException
/*      */   {
/*  353 */     Folder retVal = (Folder)super.snapshotItem();
/*  354 */     if (this.parent != null) {
/*  355 */       retVal.parent = ((Folder)this.parent.snapshotItem());
/*      */     }
/*  357 */     return retVal;
/*      */   }
/*      */   
/*      */ 
/*      */   public boolean inTrash()
/*      */   {
/*  363 */     if (this.mId <= 18)
/*  364 */       return this.mId == 3;
/*  365 */     return this.parent.inTrash();
/*      */   }
/*      */   
/*      */   public boolean inSpam()
/*      */   {
/*  370 */     return this.mId == 4;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public boolean isHidden()
/*      */   {
/*  380 */     switch (this.mId) {
/*      */     case 1: 
/*  382 */       return false;
/*      */     case 11: 
/*  384 */       return true;
/*      */     }
/*  386 */     return this.parent.isHidden();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public boolean isDescendant(Folder folder)
/*      */     throws ServiceException
/*      */   {
/*      */     for (;;)
/*      */     {
/*  398 */       int parentId = folder.getFolderId();
/*  399 */       if (parentId == getId())
/*  400 */         return true;
/*  401 */       if (parentId == 11)
/*  402 */         return false;
/*  403 */       folder = folder.getMailbox().getFolderById(null, parentId);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   short checkRights(short rightsNeeded, Account authuser, boolean asAdmin)
/*      */     throws ServiceException
/*      */   {
/*  441 */     if (rightsNeeded == 0) {
/*  442 */       return rightsNeeded;
/*      */     }
/*      */     
/*  445 */     if ((authuser == null) || (authuser.getId().equals(this.mMailbox.getAccountId()))) {
/*  446 */       return rightsNeeded;
/*      */     }
/*  448 */     if (AccessManager.getInstance().canAccessAccount(authuser, getAccount(), asAdmin)) {
/*  449 */       return rightsNeeded;
/*      */     }
/*  451 */     return checkACL(rightsNeeded, authuser, asAdmin);
/*      */   }
/*      */   
/*      */ 
/*      */   public RetentionPolicy getRetentionPolicy()
/*      */   {
/*  457 */     return this.retentionPolicy;
/*      */   }
/*      */   
/*      */   public void setRetentionPolicy(RetentionPolicy rp) throws ServiceException {
/*  461 */     if (!canAccess((short)256)) {
/*  462 */       throw ServiceException.PERM_DENIED("you do not have admin rights to folder " + getPath());
/*      */     }
/*      */     
/*  465 */     markItemModified(33554432);
/*  466 */     this.retentionPolicy = (rp == null ? new RetentionPolicy() : rp);
/*  467 */     saveMetadata();
/*      */   }
/*      */   
/*      */ 
/*      */   public MailItem getParent()
/*      */     throws ServiceException
/*      */   {
/*  474 */     return this.parent != null ? this.parent : super.getFolder();
/*      */   }
/*      */   
/*      */   Folder getFolder() throws ServiceException {
/*  478 */     return this.parent != null ? this.parent : super.getFolder();
/*      */   }
/*      */   
/*      */   public boolean hasSubfolders()
/*      */   {
/*  483 */     return (this.subfolders != null) && (!this.subfolders.isEmpty());
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   Folder findSubfolder(String name)
/*      */   {
/*  493 */     if ((name == null) || (this.subfolders == null)) {
/*  494 */       return null;
/*      */     }
/*  496 */     name = StringUtil.trimTrailingSpaces(name);
/*  497 */     return (Folder)this.subfolders.get(name.toLowerCase());
/*      */   }
/*      */   
/*      */   private static final class SortByName implements java.util.Comparator<Folder>
/*      */   {
/*      */     public int compare(Folder f1, Folder f2) {
/*  503 */       String n1 = f1.getName();
/*  504 */       String n2 = f2.getName();
/*  505 */       return n1.compareToIgnoreCase(n2);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public List<Folder> getSubfolders(OperationContext octxt)
/*      */     throws ServiceException
/*      */   {
/*  513 */     if (this.subfolders == null) {
/*  514 */       return Collections.emptyList();
/*      */     }
/*  516 */     ArrayList<Folder> visible = new ArrayList();
/*  517 */     if ((octxt == null) || (octxt.getAuthenticatedUser() == null)) {
/*  518 */       visible.addAll(this.subfolders.values());
/*      */     } else {
/*  520 */       for (Folder subfolder : this.subfolders.values()) {
/*  521 */         if (subfolder.canAccess((short)1, octxt.getAuthenticatedUser(), octxt.isUsingAdminPrivileges())) {
/*  522 */           visible.add(subfolder);
/*      */         }
/*      */       }
/*      */     }
/*  526 */     Collections.sort(visible, new SortByName(null));
/*  527 */     return visible;
/*      */   }
/*      */   
/*      */ 
/*      */   public List<Folder> getSubfolderHierarchy(OperationContext octxt)
/*      */     throws ServiceException
/*      */   {
/*  534 */     ArrayList<Folder> subfolders = new ArrayList();
/*  535 */     subfolders.add(this);
/*  536 */     List<Folder> visible = getSubfolders(octxt);
/*  537 */     for (Folder f : visible) {
/*  538 */       subfolders.add(f);
/*  539 */       subfolders.addAll(f.getSubfolderHierarchy(octxt));
/*      */     }
/*  541 */     return subfolders;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public List<Folder> getSubfolderHierarchy()
/*      */   {
/*  549 */     return accumulateHierarchy(new ArrayList());
/*      */   }
/*      */   
/*      */   private List<Folder> accumulateHierarchy(List<Folder> list) {
/*  553 */     list.add(this);
/*  554 */     if (this.subfolders != null) {
/*  555 */       for (Folder subfolder : this.subfolders.values()) {
/*  556 */         subfolder.accumulateHierarchy(list);
/*      */       }
/*      */     }
/*  559 */     return list;
/*      */   }
/*      */   
/*      */   public void setParent(Folder folder) {
/*  563 */     this.parent = folder;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void updateSize(int countDelta, int deletedDelta, long sizeDelta)
/*      */     throws ServiceException
/*      */   {
/*  573 */     if (!trackSize()) {
/*  574 */       return;
/*      */     }
/*  576 */     markItemModified(16);
/*  577 */     if (countDelta > 0) {
/*  578 */       updateUIDNEXT();
/*      */     }
/*  580 */     if (countDelta != 0) {
/*  581 */       updateHighestMODSEQ();
/*      */     }
/*      */     
/*  584 */     if ((countDelta != 0) || (sizeDelta != 0L) || (deletedDelta == 0)) {
/*  585 */       this.imapRECENT = -1;
/*      */     }
/*      */     
/*  588 */     this.mData.size = Math.max(0L, this.mData.size + countDelta);
/*  589 */     this.totalSize = Math.max(0L, this.totalSize + sizeDelta);
/*  590 */     this.deletedCount = ((int)Math.min(Math.max(0, this.deletedCount + deletedDelta), this.mData.size));
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   void setSize(long count, int deletedCount, long totalSize, int deletedUnread)
/*      */     throws ServiceException
/*      */   {
/*  599 */     if (!trackSize()) {
/*  600 */       return;
/*      */     }
/*  602 */     markItemModified(16);
/*  603 */     if (count > this.mData.size) {
/*  604 */       updateUIDNEXT();
/*      */     }
/*  606 */     if (count != this.mData.size) {
/*  607 */       updateHighestMODSEQ();
/*  608 */       this.imapRECENT = -1;
/*      */     }
/*      */     
/*  611 */     this.mData.size = count;
/*  612 */     this.totalSize = totalSize;
/*  613 */     this.deletedCount = deletedCount;
/*  614 */     this.deletedUnreadCount = deletedUnread;
/*      */   }
/*      */   
/*      */   protected void updateUnread(int delta, int deletedDelta) throws ServiceException {
/*  618 */     if (!trackUnread()) {
/*  619 */       return;
/*      */     }
/*  621 */     super.updateUnread(delta, deletedDelta);
/*      */     
/*  623 */     if (deletedDelta != 0) {
/*  624 */       markItemModified(1);
/*  625 */       this.deletedUnreadCount = Math.min(Math.max(0, this.deletedUnreadCount + deletedDelta), this.mData.unreadCount);
/*      */     }
/*      */     
/*  628 */     if (delta != 0) {
/*  629 */       updateHighestMODSEQ();
/*      */     }
/*      */   }
/*      */   
/*      */   void updateUIDNEXT()
/*      */     throws ServiceException
/*      */   {
/*  636 */     int uidnext = this.mMailbox.getLastItemId() + 1;
/*  637 */     if ((trackImapStats()) && (this.imapUIDNEXT < uidnext)) {
/*  638 */       markItemModified(16);
/*  639 */       this.imapUIDNEXT = uidnext;
/*      */     }
/*      */   }
/*      */   
/*      */   void updateHighestMODSEQ()
/*      */     throws ServiceException
/*      */   {
/*  646 */     int modseq = this.mMailbox.getOperationChangeID();
/*  647 */     if ((trackImapStats()) && (this.imapMODSEQ < modseq)) {
/*  648 */       markItemModified(16);
/*  649 */       this.imapMODSEQ = modseq;
/*      */     }
/*      */   }
/*      */   
/*      */   void checkpointRECENT()
/*      */     throws ServiceException
/*      */   {
/*  656 */     if (this.imapRECENTCutoff == this.mMailbox.getLastItemId()) {
/*  657 */       return;
/*      */     }
/*  659 */     markItemModified(268435456);
/*  660 */     this.imapRECENT = 0;
/*  661 */     this.imapRECENTCutoff = this.mMailbox.getLastItemId();
/*  662 */     saveFolderCounts(false);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   protected void saveFolderCounts(boolean initial)
/*      */     throws ServiceException
/*      */   {
/*  671 */     if (initial) {
/*  672 */       this.imapUIDNEXT = (this.mMailbox.getLastItemId() + 1);
/*  673 */       this.imapMODSEQ = this.mMailbox.getLastChangeID();
/*      */     }
/*  675 */     DbMailItem.persistCounts(this, encodeMetadata());
/*  676 */     ZimbraLog.mailbox.debug("\"%s\": updating folder counts (c%d/d%d/u%d/du%d/s%d)", new Object[] { getName(), Long.valueOf(this.mData.size), Integer.valueOf(this.deletedCount), Integer.valueOf(this.mData.unreadCount), Integer.valueOf(this.deletedUnreadCount), Long.valueOf(this.totalSize) });
/*      */   }
/*      */   
/*      */ 
/*      */   boolean isTaggable()
/*      */   {
/*  682 */     return false;
/*      */   }
/*      */   
/*      */   boolean isCopyable()
/*      */   {
/*  687 */     return false;
/*      */   }
/*      */   
/*      */   boolean isMovable()
/*      */   {
/*  692 */     return (this.attributes & 0x1) == 0;
/*      */   }
/*      */   
/*      */   boolean isMutable() {
/*  696 */     return (this.attributes & 0x1) == 0;
/*      */   }
/*      */   
/*      */   boolean canHaveChildren()
/*      */   {
/*  701 */     return true;
/*      */   }
/*      */   
/*      */   public boolean isDeletable()
/*      */   {
/*  706 */     return (this.attributes & 0x1) == 0;
/*      */   }
/*      */   
/*      */   boolean isLeafNode()
/*      */   {
/*  711 */     return false;
/*      */   }
/*      */   
/*      */   boolean trackUnread()
/*      */   {
/*  716 */     return (this.attributes & 0x2) == 0;
/*      */   }
/*      */   
/*      */   boolean trackSize() {
/*  720 */     return (this.attributes & 0x2) == 0;
/*      */   }
/*      */   
/*      */   boolean trackImapStats() {
/*  724 */     return (this.attributes & 0x2) == 0;
/*      */   }
/*      */   
/*      */   boolean canParent(MailItem child)
/*      */   {
/*  729 */     return child instanceof Folder;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   boolean canContain(MailItem child)
/*      */   {
/*  739 */     if (!canContain(child.getType()))
/*  740 */       return false;
/*  741 */     if ((child instanceof Folder))
/*      */     {
/*  743 */       for (Folder folder = this; folder.getId() != 11; folder = folder.parent)
/*  744 */         if (folder.getId() == child.getId())
/*  745 */           return false;
/*      */     }
/*  747 */     return true;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   boolean canContain(MailItem.Type type)
/*      */   {
/*  762 */     if ((type == MailItem.Type.TAG ? 1 : 0) != (this.mId == 8 ? 1 : 0))
/*  763 */       return false;
/*  764 */     if ((type == MailItem.Type.CONVERSATION ? 1 : 0) != (this.mId == 9 ? 1 : 0))
/*  765 */       return false;
/*  766 */     if ((type == MailItem.Type.FOLDER) && (!this.mMailbox.isChildFolderPermitted(this.mId))) {
/*  767 */       return false;
/*      */     }
/*  769 */     return true;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   static Folder create(int id, String uuid, Mailbox mbox, Folder parent, String name, byte attributes, MailItem.Type view, int flags, Color color, Long date, String url, MailItem.CustomMetadata custom)
/*      */     throws ServiceException
/*      */   {
/*  807 */     if (id != 11) {
/*  808 */       if ((parent == null) || (!parent.canContain(MailItem.Type.FOLDER))) {
/*  809 */         throw MailServiceException.CANNOT_CONTAIN(parent, MailItem.Type.FOLDER);
/*      */       }
/*  811 */       name = validateItemName(name);
/*  812 */       if (parent.findSubfolder(name) != null)
/*  813 */         throw MailServiceException.ALREADY_EXISTS(name);
/*  814 */       if (!parent.canAccess((short)512)) {
/*  815 */         throw ServiceException.PERM_DENIED("you do not have the required rights on the parent folder");
/*      */       }
/*      */     }
/*  818 */     if (view == MailItem.Type.INVITE) {
/*  819 */       throw MailServiceException.INVALID_TYPE(view.toString());
/*      */     }
/*      */     
/*  822 */     MailItem.UnderlyingData data = new MailItem.UnderlyingData();
/*  823 */     data.uuid = uuid;
/*  824 */     data.id = id;
/*  825 */     data.type = MailItem.Type.FOLDER.toByte();
/*  826 */     data.folderId = (id == 11 ? id : parent.getId());
/*  827 */     data.parentId = data.folderId;
/*  828 */     data.date = (date == null ? mbox.getOperationTimestamp() : (int)(date.longValue() / 1000L));
/*  829 */     data.setFlags((flags | Flag.toBitmask(mbox.getAccount().getDefaultFolderFlags())) & Flag.FLAGS_FOLDER);
/*  830 */     data.name = name;
/*  831 */     data.setSubject(name);
/*  832 */     data.metadata = encodeMetadata(color, 1, 1, custom, attributes, view, null, new SyncData(url), id + 1, 0L, mbox.getOperationChangeID(), -1, 0, 0, 0, null, false, -1);
/*      */     
/*  834 */     data.contentChanged(mbox);
/*  835 */     ZimbraLog.mailop.info("adding folder %s: id=%d, parentId=%d.", new Object[] { name, Integer.valueOf(data.id), Integer.valueOf(data.parentId) });
/*  836 */     new DbMailItem(mbox).create(data);
/*      */     
/*  838 */     Folder folder = new Folder(mbox, data);
/*  839 */     folder.finishCreation(parent);
/*  840 */     return folder;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void setDefaultView(MailItem.Type view)
/*      */     throws ServiceException
/*      */   {
/*  850 */     if (!isMutable()) {
/*  851 */       throw MailServiceException.IMMUTABLE_OBJECT(this.mId);
/*      */     }
/*  853 */     if (!canAccess((short)2)) {
/*  854 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/*  856 */     if (view == this.defaultView) {
/*  857 */       return;
/*      */     }
/*  859 */     markItemModified(1048576);
/*  860 */     this.defaultView = view;
/*  861 */     saveMetadata();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void setUrl(String url)
/*      */     throws ServiceException
/*      */   {
/*  883 */     if (url == null) {
/*  884 */       url = "";
/*      */     }
/*  886 */     if (getUrl().equals(url)) {
/*  887 */       return;
/*      */     }
/*  889 */     if ((getUrl().isEmpty()) && (!url.isEmpty())) {
/*  890 */       throw MailServiceException.CANNOT_SUBSCRIBE(this.mId);
/*      */     }
/*  892 */     if (!isMutable()) {
/*  893 */       throw MailServiceException.IMMUTABLE_OBJECT(this.mId);
/*      */     }
/*  895 */     if (!canAccess((short)2)) {
/*  896 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/*  898 */     markItemModified(262144);
/*  899 */     this.syncData = new SyncData(url);
/*  900 */     saveMetadata();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void setWebOfflineSyncDays(int days)
/*      */     throws ServiceException
/*      */   {
/*  910 */     if (!canAccess((short)2)) {
/*  911 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/*  913 */     if ((days < 0) || (days > getAccount().getWebClientOfflineSyncMaxDays())) {
/*  914 */       throw ServiceException.INVALID_REQUEST("invalid web offline folder sync days: " + days, null);
/*      */     }
/*  916 */     markItemModified(524288);
/*  917 */     this.webOfflineSyncDays = days;
/*  918 */     saveMetadata();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public int getWebOfflineSyncDays()
/*      */     throws ServiceException
/*      */   {
/*  929 */     int id = getId();
/*  930 */     if ((this.webOfflineSyncDays < 0) && ((id == 2) || (id == 5) || (id == 6) || (id == 3)))
/*      */     {
/*      */ 
/*      */ 
/*  934 */       return getAccount().getWebClientOfflineSyncMaxDays(); }
/*  935 */     if (this.webOfflineSyncDays < 0) {
/*  936 */       return 0;
/*      */     }
/*  938 */     return this.webOfflineSyncDays;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void setSubscriptionData(String guid, long date)
/*      */     throws ServiceException
/*      */   {
/*  956 */     if (getUrl().isEmpty()) {
/*  957 */       return;
/*      */     }
/*  959 */     if (!isMutable()) {
/*  960 */       throw MailServiceException.IMMUTABLE_OBJECT(this.mId);
/*      */     }
/*  962 */     if (!canAccess((short)2)) {
/*  963 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/*  965 */     markItemModified(262144);
/*  966 */     this.syncData = new SyncData(getUrl(), guid, date);
/*  967 */     saveMetadata();
/*      */   }
/*      */   
/*      */   void setSyncDate(long date) throws ServiceException {
/*  971 */     if (!canAccess((short)2)) {
/*  972 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/*  974 */     markItemModified(262144);
/*  975 */     if (this.syncData == null) {
/*  976 */       this.syncData = new SyncData(null, null, date);
/*      */     } else {
/*  978 */       this.syncData.lastDate = date;
/*      */     }
/*  980 */     saveMetadata();
/*      */   }
/*      */   
/*      */   public boolean isActiveSyncDisabled() {
/*  984 */     return this.activeSyncDisabled;
/*      */   }
/*      */   
/*      */   public void setActiveSyncDisabled(boolean disableActiveSync) throws ServiceException {
/*  988 */     if (!canAccess((short)2)) {
/*  989 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/*      */     
/*  992 */     if (this.mId < 256) {
/*  993 */       ZimbraLog.mailop.warn("Cannot disable activesync access for system folder " + this.mId);
/*  994 */       return;
/*      */     }
/*      */     
/*  997 */     markItemModified(67108864);
/*  998 */     this.activeSyncDisabled = disableActiveSync;
/*  999 */     saveMetadata();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void alterUnread(boolean unread)
/*      */     throws ServiceException
/*      */   {
/* 1011 */     if (unread)
/* 1012 */       throw ServiceException.INVALID_REQUEST("folders can only be marked read", null);
/* 1013 */     if (!canAccess((short)1))
/* 1014 */       throw ServiceException.PERM_DENIED("you do not have sufficient permissions on the folder");
/* 1015 */     if (!isUnread()) {
/* 1016 */       return;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/* 1021 */     List<MailItem.UnderlyingData> unreaddata = DbMailItem.getUnreadMessages(this);
/* 1022 */     if (canAccess((short)2)) {
/* 1023 */       Set<Integer> conversations = new java.util.HashSet(unreaddata.size());
/* 1024 */       for (MailItem.UnderlyingData data : unreaddata) {
/* 1025 */         if (data.parentId > 0) {
/* 1026 */           conversations.add(Integer.valueOf(data.parentId));
/*      */         }
/*      */       }
/* 1029 */       this.mMailbox.getItemById(conversations, MailItem.Type.CONVERSATION);
/*      */     }
/*      */     
/*      */ 
/*      */ 
/* 1034 */     List<Integer> targets = new ArrayList();
/* 1035 */     for (MailItem.UnderlyingData data : unreaddata) {
/* 1036 */       Message msg = this.mMailbox.getMessage(data);
/* 1037 */       if ((msg.checkChangeID()) || (!msg.canAccess((short)2))) {
/* 1038 */         msg.updateUnread(-1, msg.isTagged(Flag.FlagInfo.DELETED) ? -1 : 0);
/* 1039 */         msg.metadataChanged();
/* 1040 */         targets.add(Integer.valueOf(msg.getId()));
/*      */       }
/*      */     }
/*      */     String state;
/*      */     String context;
/* 1045 */     if ((ZimbraLog.mailop.isDebugEnabled()) && (targets.size() > 0)) {
/* 1046 */       state = unread ? "unread" : "read";
/* 1047 */       context = getMailopContext(this);
/* 1048 */       for (List<Integer> ids : com.zimbra.common.util.ListUtil.split(targets, 200)) {
/* 1049 */         ZimbraLog.mailop.debug("marking messages in %s as %s.  ids: %s", new Object[] { context, state, StringUtil.join(",", ids) });
/*      */       }
/*      */     }
/* 1052 */     DbMailItem.alterUnread(this.mMailbox, targets, unread);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void alterTag(Tag tag, boolean newValue)
/*      */     throws ServiceException
/*      */   {
/* 1072 */     if ((!(tag instanceof Flag)) || ((((Flag)tag).toBitmask() & Flag.FLAGS_FOLDER) == 0)) {
/* 1073 */       super.alterTag(tag, newValue);
/* 1074 */       return;
/*      */     }
/*      */     
/* 1077 */     if (newValue == isTagged(tag)) {
/* 1078 */       return;
/*      */     }
/* 1080 */     boolean isNoInheritFlag = tag.getId() == Flag.ID_NO_INHERIT;
/* 1081 */     if (!canAccess((short)(isNoInheritFlag ? 256 : 2))) {
/* 1082 */       throw ServiceException.PERM_DENIED("you do not have the necessary privileges on the folder");
/*      */     }
/* 1084 */     ACL effectiveACL = isNoInheritFlag ? getEffectiveACL() : null;
/* 1085 */     if ((effectiveACL != null) && (effectiveACL.isEmpty())) {
/* 1086 */       effectiveACL = null;
/*      */     }
/*      */     
/* 1089 */     markItemModified((tag instanceof Flag) ? 4 : 2);
/* 1090 */     tagChanged(tag, newValue);
/*      */     
/* 1092 */     if (ZimbraLog.mailop.isDebugEnabled()) {
/* 1093 */       ZimbraLog.mailop.debug("setting " + getMailopContext(tag) + " for " + getMailopContext(this));
/*      */     }
/* 1095 */     com.zimbra.cs.db.DbTag.alterTag(tag, Arrays.asList(new Integer[] { Integer.valueOf(this.mId) }), newValue);
/*      */     
/* 1097 */     if (isNoInheritFlag) {
/* 1098 */       if ((!newValue) && (this.rights != null))
/*      */       {
/* 1100 */         this.rights = null;
/* 1101 */         saveMetadata();
/* 1102 */       } else if (newValue)
/*      */       {
/*      */ 
/* 1105 */         this.rights = effectiveACL;
/* 1106 */         saveMetadata();
/*      */       }
/*      */       
/* 1109 */       markItemModified(2097152);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   void rename(String name, Folder target)
/*      */     throws ServiceException
/*      */   {
/* 1123 */     name = validateItemName(name);
/* 1124 */     boolean renamed = !name.equals(this.mData.name);
/* 1125 */     if ((!renamed) && (target == this.parent))
/* 1126 */       return;
/* 1127 */     String oldName = this.mData.name;
/* 1128 */     Folder oldParent = target == this.parent ? this.parent : null;
/* 1129 */     super.rename(name, target);
/* 1130 */     if (oldParent != null) {
/* 1131 */       oldParent.subfolderRenamed(oldName, name);
/*      */     }
/* 1133 */     if (this.rights != null) {
/* 1134 */       queueForAclPush();
/*      */     }
/*      */     
/*      */ 
/* 1138 */     contentChanged();
/*      */   }
/*      */   
/*      */   private void subfolderRenamed(String oldName, String name) {
/* 1142 */     Folder child = (Folder)this.subfolders.remove(oldName.toLowerCase());
/* 1143 */     this.subfolders.put(name.toLowerCase(), child);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   boolean move(Folder target)
/*      */     throws ServiceException
/*      */   {
/* 1152 */     markItemModified(768);
/* 1153 */     if (this.mData.folderId == target.getId())
/* 1154 */       return false;
/* 1155 */     if (!isMovable())
/* 1156 */       throw MailServiceException.IMMUTABLE_OBJECT(this.mId);
/* 1157 */     if (!canAccess((short)8))
/* 1158 */       throw ServiceException.PERM_DENIED("you do not have the required permissions");
/* 1159 */     if ((target.getId() != 3) && (target.getId() != 4) && (!target.canAccess((short)4)))
/* 1160 */       throw ServiceException.PERM_DENIED("you do not have the required permissions");
/* 1161 */     if (!target.canContain(this)) {
/* 1162 */       throw MailServiceException.CANNOT_CONTAIN();
/*      */     }
/*      */     
/* 1165 */     boolean fromTrash = inTrash();
/* 1166 */     boolean toTrash = target.inTrash();
/* 1167 */     if ((!fromTrash) && (toTrash)) {
/* 1168 */       onSoftDelete();
/*      */     }
/*      */     
/*      */ 
/* 1172 */     this.parent.removeChild(this);
/* 1173 */     target.addChild(this);
/*      */     
/* 1175 */     ZimbraLog.mailop.info("moving %s to %s", new Object[] { getMailopContext(this), getMailopContext(target) });
/*      */     
/*      */ 
/* 1178 */     DbMailItem.setFolder(this, target);
/* 1179 */     this.mData.folderId = target.getId();
/* 1180 */     this.mData.parentId = target.getId();
/* 1181 */     metadataChanged();
/*      */     
/* 1183 */     if (this.rights != null) {
/* 1184 */       queueForAclPush();
/*      */     }
/*      */     
/* 1187 */     return true;
/*      */   }
/*      */   
/*      */   private void onSoftDelete() throws ServiceException {
/* 1191 */     alterUnread(false);
/* 1192 */     if (this.subfolders != null) {
/* 1193 */       for (Folder subfolder : this.subfolders.values()) {
/* 1194 */         subfolder.onSoftDelete();
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   void addChild(MailItem child) throws ServiceException
/*      */   {
/* 1201 */     addChild(child, true);
/*      */   }
/*      */   
/*      */   void addChild(MailItem child, boolean newChild) throws ServiceException {
/* 1205 */     if ((child == null) || (!canParent(child)))
/* 1206 */       throw MailServiceException.CANNOT_CONTAIN();
/* 1207 */     if (child == this) {
/* 1208 */       if (this.mId != 11) {
/* 1209 */         throw MailServiceException.CANNOT_CONTAIN();
/*      */       }
/* 1211 */     } else if (!(child instanceof Folder)) {
/* 1212 */       super.addChild(child);
/*      */     } else {
/* 1214 */       if (newChild) {
/* 1215 */         markItemModified(1024);
/*      */       }
/* 1217 */       Folder subfolder = (Folder)child;
/* 1218 */       if (this.subfolders == null) {
/* 1219 */         this.subfolders = new java.util.LinkedHashMap();
/*      */       } else {
/* 1221 */         Folder existing = findSubfolder(subfolder.getName());
/* 1222 */         if (existing == child) {
/* 1223 */           return;
/*      */         }
/* 1225 */         if (existing != null) {
/* 1226 */           throw MailServiceException.ALREADY_EXISTS(subfolder.getName());
/*      */         }
/*      */       }
/* 1229 */       this.subfolders.put(subfolder.getName().toLowerCase(), subfolder);
/* 1230 */       subfolder.parent = this;
/*      */     }
/*      */   }
/*      */   
/*      */   void removeChild(MailItem child) throws ServiceException
/*      */   {
/* 1236 */     if (child == null)
/* 1237 */       throw MailServiceException.CANNOT_CONTAIN();
/* 1238 */     if (!(child instanceof Folder)) {
/* 1239 */       super.removeChild(child);
/*      */     } else {
/* 1241 */       markItemModified(1024);
/* 1242 */       Folder subfolder = (Folder)child;
/* 1243 */       if (this.subfolders == null) {
/* 1244 */         throw MailServiceException.IS_NOT_CHILD();
/*      */       }
/* 1246 */       if (this.subfolders.remove(subfolder.getName().toLowerCase()) == null) {
/* 1247 */         if (this.subfolders.containsValue(subfolder))
/*      */         {
/*      */ 
/* 1250 */           Iterator<Folder> it = this.subfolders.values().iterator();
/* 1251 */           while (it.hasNext()) {
/* 1252 */             if (subfolder.equals(it.next())) {
/* 1253 */               it.remove();
/*      */             }
/*      */           }
/*      */         }
/*      */         else {
/* 1258 */           throw MailServiceException.IS_NOT_CHILD();
/*      */         }
/*      */       }
/* 1261 */       subfolder.parent = null;
/*      */     }
/*      */   }
/*      */   
/*      */   void delete(boolean writeTombstones)
/*      */     throws ServiceException
/*      */   {
/* 1268 */     if (hasSubfolders()) {
/* 1269 */       List<Folder> allSubfolders = getSubfolderHierarchy();
/*      */       
/*      */ 
/*      */ 
/*      */ 
/* 1274 */       for (int i = allSubfolders.size() - 1; i > 0; i--) {
/* 1275 */         Folder subfolder = (Folder)allSubfolders.get(i);
/* 1276 */         subfolder.delete(writeTombstones);
/*      */       }
/*      */     }
/* 1279 */     ZimbraLog.mailbox.info("deleting folder id=%d,path=%s", new Object[] { Integer.valueOf(getId()), getPath() });
/* 1280 */     super.delete(writeTombstones);
/*      */     
/* 1282 */     if (this.rights != null) {
/* 1283 */       queueForAclPush();
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   MailItem.PendingDelete getDeletionInfo()
/*      */     throws ServiceException
/*      */   {
/* 1305 */     if (!canAccess((short)8))
/* 1306 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the item");
/* 1307 */     return DbMailItem.getLeafNodes(this);
/*      */   }
/*      */   
/*      */   void propagateDeletion(MailItem.PendingDelete info) throws ServiceException
/*      */   {
/* 1312 */     if (info.incomplete) {
/* 1313 */       info.cascadeIds = DbMailItem.markDeletionTargets(this.mMailbox, info.itemIds.getIds(EnumSet.of(MailItem.Type.MESSAGE, MailItem.Type.CHAT)), info.modifiedIds);
/*      */     }
/*      */     else {
/* 1316 */       info.cascadeIds = DbMailItem.markDeletionTargets(this, info.modifiedIds);
/*      */     }
/* 1318 */     if (info.cascadeIds != null) {
/* 1319 */       info.modifiedIds.removeAll(info.cascadeIds);
/*      */     }
/* 1321 */     super.propagateDeletion(info);
/*      */   }
/*      */   
/*      */   void purgeCache(MailItem.PendingDelete info, boolean purgeItem)
/*      */     throws ServiceException
/*      */   {
/* 1327 */     this.mMailbox.purge(MailItem.Type.CONVERSATION);
/*      */     
/* 1329 */     this.mMailbox.getItemById(ArrayUtil.toIntArray(info.modifiedIds), MailItem.Type.CONVERSATION);
/*      */     
/* 1331 */     super.purgeCache(info, purgeItem);
/*      */   }
/*      */   
/*      */ 
/*      */   static int purgeMessages(Mailbox mbox, Folder folder, long beforeDate, Boolean unread, boolean useChangeDate, boolean deleteEmptySubfolders, Integer maxItems)
/*      */     throws ServiceException
/*      */   {
/* 1338 */     if ((beforeDate <= 0L) || (beforeDate >= mbox.getOperationTimestampMillis())) {
/* 1339 */       return 0;
/*      */     }
/*      */     
/*      */ 
/* 1343 */     boolean allFolders = folder == null;
/* 1344 */     List<Folder> folders = allFolders ? null : folder.getSubfolderHierarchy();
/*      */     
/*      */ 
/* 1347 */     if ((folders != null) && (useChangeDate)) {
/* 1348 */       Iterator<Folder> iter = folders.iterator();
/*      */       
/* 1350 */       if (iter.hasNext()) {
/* 1351 */         iter.next();
/*      */       }
/*      */       
/* 1354 */       while (iter.hasNext()) {
/* 1355 */         Folder f = (Folder)iter.next();
/* 1356 */         if (f.getChangeDate() >= beforeDate) {
/* 1357 */           ZimbraLog.purge.info("Skipping the recently modified/moved folder %s", new Object[] { f.getPath() });
/* 1358 */           iter.remove();
/*      */         }
/*      */       }
/*      */     }
/* 1362 */     MailItem.PendingDelete info = DbMailItem.getLeafNodes(mbox, folders, (int)(beforeDate / 1000L), allFolders, unread, useChangeDate, maxItems);
/* 1363 */     delete(mbox, info, null, false, false);
/*      */     
/* 1365 */     if (deleteEmptySubfolders)
/*      */     {
/* 1367 */       for (int i = folders.size() - 1; i >= 1; i--) {
/* 1368 */         Folder f = (Folder)folders.get(i);
/* 1369 */         long date = useChangeDate ? f.getChangeDate() : f.getDate();
/* 1370 */         if ((f.getItemCount() <= 0L) && (date < beforeDate)) {
/* 1371 */           f.delete(false);
/*      */         }
/*      */       }
/*      */     }
/*      */     
/* 1376 */     List<Integer> ids = info.itemIds.getIds(MailItem.Type.MESSAGE);
/* 1377 */     return ids == null ? 0 : ids.size();
/*      */   }
/*      */   
/*      */   void migrateDefaultView(MailItem.Type view) throws ServiceException
/*      */   {
/* 1382 */     if (!canAccess((short)2)) {
/* 1383 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the folder");
/*      */     }
/* 1385 */     if (view == this.defaultView) {
/* 1386 */       return;
/*      */     }
/* 1388 */     markItemModified(1048576);
/* 1389 */     this.defaultView = view;
/* 1390 */     saveMetadata();
/*      */   }
/*      */   
/*      */   void decodeMetadata(Metadata meta) throws ServiceException
/*      */   {
/* 1395 */     super.decodeMetadata(meta);
/*      */     
/*      */     MailItem.Type view;
/*      */     
/* 1399 */     switch (this.mId) {
/*      */     case 2: 
/*      */     case 4: 
/*      */     case 5: 
/*      */     case 6: 
/* 1404 */       view = MailItem.Type.MESSAGE;
/* 1405 */       break;
/*      */     case 10: 
/* 1407 */       view = MailItem.Type.APPOINTMENT;
/* 1408 */       break;
/*      */     case 15: 
/* 1410 */       view = MailItem.Type.TASK;
/* 1411 */       break;
/*      */     case 7: 
/*      */     case 13: 
/* 1414 */       view = MailItem.Type.CONTACT;
/* 1415 */       break;
/*      */     case 14: 
/* 1417 */       view = MailItem.Type.MESSAGE;
/* 1418 */       break;
/*      */     case 3: case 8: case 9: case 11: case 12: default: 
/* 1420 */       view = MailItem.Type.UNKNOWN;
/*      */     }
/*      */     
/* 1423 */     byte bview = (byte)(int)meta.getLong("vt", -1L);
/* 1424 */     this.defaultView = (bview >= 0 ? MailItem.Type.of(bview) : view);
/*      */     
/* 1426 */     this.attributes = ((byte)(int)meta.getLong("a", 0L));
/* 1427 */     this.totalSize = meta.getLong("sz", 0L);
/* 1428 */     this.imapUIDNEXT = ((int)meta.getLong("unxt", 0L));
/* 1429 */     this.imapMODSEQ = ((int)meta.getLong("mseq", 0L));
/* 1430 */     this.imapRECENT = ((int)meta.getLong("i4l", -1L));
/* 1431 */     this.imapRECENTCutoff = ((int)meta.getLong("i4r", 0L));
/* 1432 */     this.deletedCount = ((int)meta.getLong("i4d", 0L));
/* 1433 */     this.deletedUnreadCount = ((int)meta.getLong("i4du", 0L));
/*      */     
/* 1435 */     if ((meta.containsKey("url")) || (meta.containsKey("sd"))) {
/* 1436 */       this.syncData = new SyncData(meta.get("url", null), meta.get("sg", null), meta.getLong("sd", 0L));
/*      */     }
/*      */     
/*      */ 
/* 1440 */     Metadata rp = meta.getMap("rp", true);
/* 1441 */     if (rp != null) {
/* 1442 */       this.retentionPolicy = RetentionPolicyManager.retentionPolicyFromMetadata(rp, true);
/*      */     } else {
/* 1444 */       this.retentionPolicy = new RetentionPolicy();
/*      */     }
/*      */     
/* 1447 */     this.activeSyncDisabled = meta.getBool("das", false);
/*      */     
/* 1449 */     this.webOfflineSyncDays = meta.getInt("wosd", -1);
/*      */   }
/*      */   
/*      */   Metadata encodeMetadata(Metadata meta)
/*      */   {
/* 1454 */     Metadata m = encodeMetadata(meta, this.mRGBColor, this.mMetaVersion, this.mVersion, this.mExtendedData, this.attributes, this.defaultView, this.rights, this.syncData, this.imapUIDNEXT, this.totalSize, this.imapMODSEQ, this.imapRECENT, this.imapRECENTCutoff, this.deletedCount, this.deletedUnreadCount, this.retentionPolicy, this.activeSyncDisabled, this.webOfflineSyncDays);
/*      */     
/*      */ 
/* 1457 */     return m;
/*      */   }
/*      */   
/*      */ 
/*      */   private static String encodeMetadata(Color color, int metaVersion, int version, MailItem.CustomMetadata custom, byte attributes, MailItem.Type view, ACL rights, SyncData fsd, int uidnext, long totalSize, int modseq, int imapRecent, int imapRecentCutoff, int deleted, int deletedUnread, RetentionPolicy rp, boolean disableActiveSync, int webOfflineSyncdDays)
/*      */   {
/* 1463 */     MailItem.CustomMetadata.CustomMetadataList extended = custom == null ? null : custom.asList();
/* 1464 */     return encodeMetadata(new Metadata(), color, metaVersion, version, extended, attributes, view, rights, fsd, uidnext, totalSize, modseq, imapRecent, imapRecentCutoff, deleted, deletedUnread, rp, disableActiveSync, webOfflineSyncdDays).toString();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   static Metadata encodeMetadata(Metadata meta, Color color, int metaVersion, int version, MailItem.CustomMetadata.CustomMetadataList extended, byte attributes, MailItem.Type view, ACL rights, SyncData fsd, int uidnext, long totalSize, int modseq, int imapRecent, int imapRecentCutoff, int deleted, int deletedUnread, RetentionPolicy rp, boolean disableActiveSync, int webOfflineSyncDays)
/*      */   {
/* 1473 */     if ((view != null) && (view != MailItem.Type.UNKNOWN)) {
/* 1474 */       meta.put("vt", view.toByte());
/*      */     }
/* 1476 */     if (attributes != 0) {
/* 1477 */       meta.put("a", attributes);
/*      */     }
/* 1479 */     if (totalSize > 0L) {
/* 1480 */       meta.put("sz", totalSize);
/*      */     }
/* 1482 */     if (uidnext > 0) {
/* 1483 */       meta.put("unxt", uidnext);
/*      */     }
/* 1485 */     if (modseq > 0) {
/* 1486 */       meta.put("mseq", modseq);
/*      */     }
/* 1488 */     if (imapRecent > 0) {
/* 1489 */       meta.put("i4l", imapRecent);
/*      */     }
/* 1491 */     if (imapRecentCutoff > 0) {
/* 1492 */       meta.put("i4r", imapRecentCutoff);
/*      */     }
/* 1494 */     if ((fsd != null) && (fsd.url != null) && (!fsd.url.isEmpty())) {
/* 1495 */       meta.put("url", fsd.url);
/* 1496 */       meta.put("sg", fsd.lastGuid);
/*      */     }
/* 1498 */     if ((fsd != null) && (fsd.lastDate > 0L)) {
/* 1499 */       meta.put("sd", fsd.lastDate);
/*      */     }
/* 1501 */     if (deleted > 0) {
/* 1502 */       meta.put("i4d", deleted);
/*      */     }
/* 1504 */     if (deletedUnread > 0) {
/* 1505 */       meta.put("i4du", deletedUnread);
/*      */     }
/* 1507 */     if ((rp != null) && (rp.isSet())) {
/* 1508 */       meta.put("rp", RetentionPolicyManager.toMetadata(rp, true));
/*      */     }
/* 1510 */     meta.put("das", disableActiveSync);
/* 1511 */     if (webOfflineSyncDays >= 0) {
/* 1512 */       meta.put("wosd", webOfflineSyncDays);
/*      */     }
/*      */     
/* 1515 */     return MailItem.encodeMetadata(meta, color, rights, metaVersion, version, extended);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public String toString()
/*      */   {
/* 1525 */     Objects.ToStringHelper helper = com.google.common.base.Objects.toStringHelper(this);
/* 1526 */     helper.add("n", getName());
/* 1527 */     appendCommonMembers(helper);
/* 1528 */     helper.add("deleted", this.deletedCount);
/* 1529 */     helper.add("del_unread", this.deletedUnreadCount);
/* 1530 */     helper.add("attributes", this.attributes);
/* 1531 */     return helper.toString();
/*      */   }
/*      */   
/*      */   protected void checkItemCreationAllowed()
/*      */     throws ServiceException
/*      */   {
/* 1537 */     if (isMutable()) {
/* 1538 */       super.checkItemCreationAllowed();
/*      */     }
/*      */   }
/*      */   
/*      */   protected long getMaxAllowedExternalShareLifetime(Account account)
/*      */   {
/* 1544 */     return AccountUtil.getMaxExternalShareLifetime(account, getDefaultView());
/*      */   }
/*      */   
/*      */   protected long getMaxAllowedInternalShareLifetime(Account account)
/*      */   {
/* 1549 */     return AccountUtil.getMaxInternalShareLifetime(account, getDefaultView());
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   boolean isShare()
/*      */   {
/* 1557 */     return isTagged(Flag.FlagInfo.NO_INHERIT);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   boolean containsShare()
/*      */     throws ServiceException
/*      */   {
/* 1566 */     if (this.subfolders != null) {
/* 1567 */       for (Folder sub : this.subfolders.values()) {
/* 1568 */         if ((sub.isShare()) || (sub.containsShare())) {
/* 1569 */           return true;
/*      */         }
/*      */       }
/*      */     }
/* 1573 */     return false;
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailbox/Folder.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */